#include "stdafx.h"
#include "PatchingUtils.h"


/* UNIFIED PATCHER */
DWORD ic_PatchProcImports ( HANDLE hProc, DWORD dFind, DWORD dReplace )
{
	DWORD ret = 0;
	/* GODMODE ON */
	BOOL  bOldKMode = SetKMode ( TRUE );
	DWORD dOldPerms = SetProcPermissions ( 0xFFFFFFFF );
	/* get process ptr prom handle */
	HDATA * hProcHD = ( HDATA * ) ( 0x80000000 | ( ( DWORD ) hProc & HANDLE_ADDRESS_MASK ) );
	PROCESS * prc = ( PROCESS * ) hProcHD->pvObj;
	/* get imports sections */
	struct ImpHdr * blockptr, * blockstart;
	blockstart = ( struct ImpHdr * ) MapPtrProc ( prc->e32.e32_vbase + prc->e32.e32_unit[IMP].rva, prc );
	/* iterate thru imports sections */
	for ( blockptr = blockstart; blockptr->imp_lookup; ++blockptr )
	{
		DWORD dOldProtect, tmp;
		/* get vectors ptr */
		DWORD * vectors = ( DWORD * ) MapPtrProc ( prc->e32.e32_vbase + blockptr->imp_address, prc );
		/* count vectors */
		DWORD * vptr = vectors;
		while ( * vptr ) ++vptr;
		DWORD vcnt = ( vptr - vectors );
		/* try to unlock imports section memory */
		if ( VirtualProtect ( vectors, vcnt * sizeof ( DWORD ), PAGE_EXECUTE_READWRITE, &dOldProtect ) )
		{
			/* find&replace */
			for ( UINT i = 0; i < vcnt; ++i )
			{
				if ( vectors[i] == dFind )
				{
					vectors[i] = dReplace;
					++ret;
				}
			}
			/* lock back */
			VirtualProtect ( vectors, vcnt * sizeof ( DWORD ), dOldProtect, &tmp );
		}
	}
	/* GODMODE OFF */
	SetProcPermissions ( dOldPerms );
	SetKMode ( bOldKMode );
	/* */
	return ret;
}

DWORD ReplaceProc (DWORD dFind, DWORD dReplace )
{
	HANDLE currentProcess = GetCurrentProcess();

	DWORD ret = 0;
	/* GODMODE ON */
	BOOL  bOldKMode = SetKMode ( TRUE );
	DWORD dOldPerms = SetProcPermissions ( 0xFFFFFFFF );

	DWORD tmp;
	DWORD* cpFn = ( DWORD* ) RemoteHeapAlloc (currentProcess, NULL, LMEM_FIXED, 2 * sizeof(DWORD));
	VirtualProtect (cpFn, 2, PAGE_EXECUTE_READWRITE, &tmp );

//	DWORD* cpFn = new DWORD[2];  //VirtualAlloc(0, 8, 0, PAGE_EXECUTE_READWRITE);

	cpFn[0] = 0xE51FF004;
	cpFn[1] = (DWORD) MapPtrToProcess((LPVOID)dReplace, currentProcess);

	DWORD * pA =  ( DWORD * ) MapPtrToProcess((LPVOID)dFind, currentProcess);

	DWORD newValue = 0xEB000000 | (((((DWORD)cpFn - (DWORD) dFind) - 8) >> 2) & 0x00FFFFFF);

	BOOL resutl = WriteProcessMemory(currentProcess, pA, &newValue, sizeof(DWORD), 0);

	/* GODMODE OFF */
	SetProcPermissions ( dOldPerms );
	SetKMode ( bOldKMode );
	/* */
	return ret;
}


HANDLE GetProcessByName(TCHAR* name)
{
	HANDLE prc = NULL;

	/* GODMODE ON */
	BOOL  bOldKMode = SetKMode ( TRUE );
	DWORD dOldPerms = SetProcPermissions ( 0xFFFFFFFF );
	
	/* find cprog */
	for ( int i = 0; i < 32; ++i )
	{
		PROCESS * tprc = ( ( PROCESS * ) KData.aInfo[KINX_PROCARRAY] ) + i;
		if ( tprc->dwVMBase && ( 0 == _wcsicmp ( tprc->lpszProcName, name ) ) )
		{
			prc = tprc->hProc;
		}
	}
	/* GODMODE OFF */
	SetProcPermissions ( dOldPerms );
	SetKMode ( bOldKMode );

	return prc;
}